//: Playground - noun: a place where people can play

import UIKit


//:  枚举: 将一组相关的值定义成共同的类型
enum enumName{            // 枚举的语法格式,可以不指定成员类型
    case caseName         // 使用case定义枚举成员值
}

enum compassPoint {                    // 用枚举表示指南针的四个方向
    case North                         // 枚举成员不会像OC进行隐式赋值
    case South
    case East
    case West
}
enum compassPoint2 {
    case North, South, East, West      // 成员值也可以横着写
}

var direction = compassPoint.North     // direction为compassPoint类型
direction = .West                      // 类型确定之后就可以有简略写法


//:  使用switch语句匹配枚举值
direction = .East
switch direction {     // 如果省略default,就必须穷举所有情况
case .North:
    print("NORTH")
case .South:
    print("SORTH")
default:
    print("123")
}


//: 关联值: 枚举可以存储和修改不同类型的关联值
enum Person {
    case Location(Double, Double)
    case Name(String)
}
var p1 = Person.Location(87.21, 90.123)
p1 = .Name("Alex")                      // 同一时间只能存储一个值
p1 = .Name("Joan")

switch p1 {
case .Location(let x, let y):
    print("X:\(x),Y:\(y)")
case .Name(let name):
    print(name)                         // Joan
}



enum Arth {
    case Number(Int)
    indirect case Add(Arth, Arth)      // indirect表示枚举成员可递归
    indirect case Mul(Arth, Arth)
}

let five = Arth.Number(5)
let four = Arth.Number(4)
let sum = Arth.Add(five, four)
let result = Arth.Mul(sum, Arth.Number(2))

func evaluate(express: Arth) -> Int{
    switch express {
    case .Number(let value):
        return value
    case .Add(let left, let right):
        return evaluate(express: left) + evaluate(express: right)
    case .Mul(let left, let right):
        return evaluate(express: left) * evaluate(express: right)
    }
}
print(result)
print(evaluate(express: result))





